Protect the polling thread setup and shutdown function by mutexes and read
authorRonald Bultje <rbultje@src.gnome.org>
Wed, 11 Apr 2007 11:08:22 +0000 (11:08 +0000)
committerRonald Bultje <rbultje@src.gnome.org>
Wed, 11 Apr 2007 11:08:22 +0000 (11:08 +0000)
        * gdk/quartz/gdkeventloop-quartz.c: Protect the polling thread
          setup and shutdown function by mutexes and read the wakeup
          pipe unconditionally and unblocking. This should make the main
          loop always be woken up when using g_idle_add() from another
          thread in the Quartz backend (#425271).

svn path=/trunk/; revision=17595

ChangeLog
gdk/quartz/gdkeventloop-quartz.c

index 7ac03789a159d1afe5d8c5a423f8d17d69dfcea4..5cfcbc3bdc33475c82326945ebc6dcfc594a5c9e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2007-04-11  Ronald S. Bultje  <rbultje@ronald.bitfreak.net>
+
+       * gdk/quartz/gdkeventloop-quartz.c: Protect the polling thread
+         setup and shutdown function by mutexes and read the wakeup
+         pipe unconditionally and unblocking. This should make the main
+         loop always be woken up when using g_idle_add() from another
+         thread in the Quartz backend (#425271).
+
 2007-04-10  Matthias Clasen  <mclasen@redhat.com>
 
        * gdk/x11/xsettings-client.[hc]: Change the XSettingsWatchFunc
index 5c0866b6b3921f2154eb79a9b440076eceb9dcd3..eb52921b1763064d99700a6de49ece22590eac76 100644 (file)
@@ -13,6 +13,7 @@ static NSEvent *current_event;
 
 static GPollFunc old_poll_func;
 
+static gboolean select_fd_waiting = FALSE;
 static pthread_t select_thread = 0;
 static int wakeup_pipe[2];
 static pthread_mutex_t pollfd_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -116,20 +117,24 @@ select_thread_func (void *arg)
 {
   int n_active_fds;
 
+  pthread_mutex_lock (&pollfd_mutex);
+  pthread_cond_signal (&ready_cond);
+
   while (1)
     {
-      pthread_mutex_lock (&pollfd_mutex);
+      char c;
+      int n;
+
       pthread_cond_wait (&ready_cond, &pollfd_mutex);
 
+      pthread_mutex_unlock (&pollfd_mutex);
+      select_fd_waiting = TRUE;
       n_active_fds = old_poll_func (pollfds, n_pollfds, -1);
-      if (pipe_pollfd->revents)
-       {
-         char c;
-         int n;
-
-         n = read (pipe_pollfd->fd, &c, 1);
-
-         g_assert (n == 1);
+      select_fd_waiting = FALSE;
+      pthread_mutex_lock (&pollfd_mutex);
+      n = read (pipe_pollfd->fd, &c, 1);
+      if (n == 1)
+        {
          g_assert (c == 'A');
 
          n_active_fds --;
@@ -143,6 +148,8 @@ select_thread_func (void *arg)
          if (CFRunLoopIsWaiting (main_thread_run_loop))
            CFRunLoopWakeUp (main_thread_run_loop);
        }
+
+      pthread_mutex_lock (&pollfd_mutex);
     }
 }
 
@@ -166,10 +173,14 @@ poll_func (GPollFD *ufds, guint nfds, gint timeout_)
         CFRunLoopAddSource (main_thread_run_loop, select_main_thread_source, kCFRunLoopDefaultMode);
 
         pipe (wakeup_pipe);
+        fcntl(wakeup_pipe[0], F_SETFL, O_NONBLOCK);
+
+        pthread_mutex_lock (&pollfd_mutex);
         pthread_create (&select_thread, NULL, select_thread_func, NULL);
-      }
+        pthread_cond_wait (&ready_cond, &pollfd_mutex);
+      } else
+        pthread_mutex_lock (&pollfd_mutex);
 
-      pthread_mutex_lock (&pollfd_mutex);
       n_pollfds = nfds;
       g_free (pollfds);
       pollfds = g_memdup (ufds, sizeof (GPollFD) * nfds);
@@ -185,10 +196,9 @@ poll_func (GPollFD *ufds, guint nfds, gint timeout_)
             }
         }
 
-      pthread_mutex_unlock (&pollfd_mutex);
-
       /* Start our thread */
       pthread_cond_signal (&ready_cond);
+      pthread_mutex_unlock (&pollfd_mutex);
     }
 
   if (timeout_ == -1)
@@ -235,12 +245,14 @@ poll_func (GPollFD *ufds, guint nfds, gint timeout_)
     }
 
   /* There were no active fds, break out of the other thread's poll() */
-  if (n_active == 0 && wakeup_pipe[1])
+  pthread_mutex_lock (&pollfd_mutex);
+  if (select_fd_waiting && wakeup_pipe[1])
     {
       char c = 'A';
 
       write (wakeup_pipe[1], &c, 1);
     }
+  pthread_mutex_unlock (&pollfd_mutex);
 
   if (event) 
     {